# indexing object by index (string)
class ObjectIndexer:
    def __init__(self):
        self.bucket = {}
    
    # make index
    def set(self, index, object):
        # validate arguments
        if index == "" or index == None:
            return
            #raise Exception
            #raise IndexerException
        
        if object == None:
            raise Exception
        
        # check whether object already exists
        already_indexed = self.find(index)
        if not already_indexed:
            self.bucket[index] = object
        else:
            raise IndexerException
    
    # find object by index
    def find(self, index):
        return self.bucket.get(index, None)

    # merge multiple ObjectIndexer, and return new ObjectIndexer Object
    @classmethod
    def merge(cls, objectIndexers):
        newObjectIndexer = ObjectIndexer()
        
        new_bucket = {}
        buckets = map(lambda x: x.getIndexer()._get_bucket(), objectIndexers)
        map(lambda x: new_bucket.update(x), buckets)
        
        newObjectIndexer._bulk_load(new_bucket)
        
        return newObjectIndexer

    # helper methods for merge class method
    def _get_bucket(self):
        return self.bucket
    
    def _bulk_load(self, index_bucket):
        self.bucket = index_bucket
    
class IndexerException(Exception):
    def __init__(self):
        pass
    
    def __str__(self):
        return "Indexer: Duplicated Name"